<?php

namespace App\V3\V3_2_7\Services;

use App\V3\V3_2_7\Models\AdminModel;
use App\V3\V3_2_7\Models\AdminSetTimeModel;
use App\V3\V3_2_7\Models\EmployeeStatusModel;
use App\V3\V3_2_7\Models\StaffRestTimeModel;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class EmployeeStatusService
{
    /**
     *主账号设置/取消时间
     * Author: zlf
     * Created at 2024/8/6 10:25
     * @param $data
     * @return JsonResponse
     */
    public static function setTime($data): ?JsonResponse
    {
        $info = AdminSetTimeModel::query()->where([
            'set_time' => $data['set_time'],
            'main_id' => $data['main_id']
        ])->first();
        if (!empty($info)) {
            $info->set_type = $info->set_type === 0 ? 1 : 0;
            $bool = $info->save();
        } else {
            $bool = AdminSetTimeModel::query()->insert($data);
        }
        if ($bool)
            return success();
        else
            return fail('', '设置失败');
    }

    public static function getTimeList($data): array
    {
        return AdminSetTimeModel::query()
            ->select(
                'id as tid',
                'set_time',
                'set_type'
            )->whereBetween('set_time', [$data['start_time'], $data['end_time']])
            ->where([
                'set_type' => 0,
                'main_id' => $data['main_id'],
            ])->get()->toArray();
    }

    public static function addAbsenceRequest($data): ?JsonResponse
    {
        $timeArr = SELF::getDatesInRange($data['start_time'], $data['end_time']);
        if (count($timeArr) !== (int)$data['rest_days']) {
            return fail('', '申请的天数有误！');
        }
        $restTimeList = StaffRestTimeModel::query()
            ->where([
                'is_repeal' => 0,
                ['is_agree', '!=', 2],
                'user_id' => $data['user_id'],
            ])->whereIn('rest_time', $timeArr)->get();
        if (!empty($restTimeList->toArray())) {
            $noAuditTime = [];
            $agreedTime = [];
            foreach ($restTimeList->toArray() as $val) {
                if ($val['is_agree'] === 0) {
                    $noAuditTime[] = $val['rest_time'];
                }
                if ($val['is_agree'] === 1) {
                    $agreedTime[] = $val['rest_time'];
                }
            }
            if (!empty($noAuditTime)) {
                return fail('', '时间：' . implode(',', $noAuditTime) . ' 您已申请,请勿重复申请!');

            }
            if (!empty($agreedTime)) {
                return fail('', '时间：' . implode(',', $agreedTime) . ' 已同意,请勿重复申请!');
            }
        }

        $forbidTimeList = AdminSetTimeModel::query()
            ->select('set_time')
            ->where([
                'set_type' => 0,
                'main_id' => $data['main_id'],
            ])->whereIn('set_time', $timeArr)
            ->pluck('set_time')->toArray();

        if (!empty($forbidTimeList)) {
            $forbidTimeArr = implode(',', $forbidTimeList);
            return fail('', '提示:时间 ' . $forbidTimeArr . ' 为重要日期，不可申请。请重新选择时间');
        }
        DB::beginTransaction();
        try {
            EmployeeStatusModel::query()->insert($data);
            if (!empty($timeArr)) {
                $tArr = [];
                foreach ($timeArr as $k => $t) {
                    $tArr[$k]['rest_time'] = $t;
                    $tArr[$k]['main_id'] = $data['main_id'];
                    $tArr[$k]['user_id'] = $data['user_id'];
                }
                StaffRestTimeModel::query()->insert($tArr);
            }
            DB::commit();
            return success();
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('员工申请休息异常' . var_export($e->getMessage(), true));
            return fail('', '添加失败！');
        }
    }

    /**
     *
     * Author: zlf
     * Created at 2024/8/6 17:03
     * @param $data
     * @return LengthAwarePaginator
     */
    public static function restWorkList($data): LengthAwarePaginator
    {
        $list = [];
        if (!empty($data['req_type'])) {//工作人员
            $idArr = EmployeeStatusModel::query()
                ->where([
                    //'is_agree' => 1,
                    'is_repeal' => 0,
                    'main_id' => $data['main_id'],
                    ['start_time', '<=', $data['set_time']],
                    ['end_time', '>=', $data['set_time']],
                ])->pluck('user_id')->toArray();
            $list = AdminModel::query()
                ->select(
                    'id as user_id',
                    'username',
                    'nickname',
                    'mobile'
                )->where([
                    'delete_flag' => 0,
                    'parent_id' => $data['main_id'],
                ])->where(function ($query) use ($idArr) {
                    if (!empty($idArr)) {
                        $query->whereNotIn('id', $idArr);
                    }
                })->orderBy('id', 'DESC')
                ->paginate($data['pageSize'], ['*'], '', $data['currentPage']);
        } else {//休息人员
            $list = EmployeeStatusModel::query()
                ->select(
                    'b.id as user_id',
                    'username',
                    'nickname',
                    'mobile'
                )->leftJoin('admin as b', 'b.id', 'employee_status.user_id')
                ->where([
                    //'is_agree' => 1,
                    'is_repeal' => 0,
                    'main_id' => $data['main_id'],
                    ['start_time', '<=', $data['set_time']],
                    ['end_time', '>=', $data['set_time']],
                ])
                ->groupBy('user_id')
                ->orderBy('employee_status.created_at', 'desc')
                ->paginate($data['pageSize'], ['*'], '', $data['currentPage']);
        }
        return $list;
    }

    public static function newRestInfo($data): int
    {
        return EmployeeStatusModel::query()->where([
            'is_agree' => 0,
            'is_repeal' => 0,
            'main_id' => $data['main_id'],
            ['user_id', '!=', $data['user_id']]
        ])->count();
    }

    public static function seeMoreList($data): array
    {
        $list = EmployeeStatusModel::query()
            ->select(
                'employee_status.id',
                'employee_status.is_agree',
                'employee_status.reason_applying',
                'employee_status.start_time',
                'employee_status.end_time',
                'employee_status.rest_days',
                'username',
                'nickname',
                'mobile',
                'user_id'
            )->leftJoin('admin as b', 'b.id', 'employee_status.user_id')
            ->where([
                /*['is_agree', '!=', 0],*/
                'main_id' => $data['main_id'],
                'employee_status.is_repeal' => 0
            ])->where(function ($query) use ($data) {
                if ($data['main_id'] !== $data['user_id']) {
                    $query->where('user_id', $data['user_id']);
                }
            })->orderBy('employee_status.created_at', 'desc')
            ->paginate($data['pageSize'], ['*'], '', $data['currentPage'])->toArray();

        if (!empty($list['data'])) {
            foreach ($list['data'] as &$val) {
                $val['is_edit'] = 1;
                if ($val['user_id'] === $data['user_id']) {
                    $val['is_edit'] = 0;
                }
            }
        }
        return $list;

    }

    /**
     *员式工作状态列表
     * Author: zlf
     * Created at 2024/8/6 17:58
     * @param $data
     * @return array[]
     */
    public static function employeeStatusList($data): array
    {
        $list = EmployeeStatusModel::query()
            ->select(
                'employee_status.id',
                'employee_status.is_agree',
                'employee_status.reason_applying',
                'employee_status.start_time',
                'employee_status.end_time',
                'employee_status.rest_days',
                'username',
                'nickname',
                'mobile',
            )->leftJoin('admin as b', 'b.id', 'employee_status.user_id')
            ->where([
                'main_id' => $data['main_id'],
                'employee_status.is_repeal' => 0
            ])->where(function ($query) use ($data) {
                if ($data['main_id'] !== $data['user_id']) {
                    $query->where('user_id', $data['user_id']);
                }
            })->orderBy('employee_status.created_at', 'desc')->get();

        $newList = [];
        $oldList = [];
        if (!empty($list)) {
            foreach ($list as $val) {
                if ($val['is_agree'] === 0) {
                    $val['is_edit'] = 0;
                    if ($data['main_id'] === $data['user_id']) {
                        $val['is_edit'] = 1;
                    }
                    $newList[] = $val;
                } else {
                    if (count($oldList) < 6) {
                        $oldList[] = $val;
                    }
                }
            }
        }
        return [
            'new_list' => $newList,
            'old_list' => $oldList,
        ];
    }

    public static function agreeRefuseRepeal($data, $reqType = 0): ?JsonResponse
    {
        $info = EmployeeStatusModel::query()->where([
            'main_id' => $data['main_id'],
            'id' => $data['id'],
        ])->first();
        if (!empty($info)) {
            DB::beginTransaction();
            try {
                if (!empty($reqType)) {
                    $info->is_agree = $data['is_agree'] ?? $info->is_agree;
                } else {
                    if ($info['user_id'] !== $data['user_id']) {
                        return fail('', '只是申请人，才能撤销！');
                    }
                    $info->is_repeal = $data['is_repeal'] ?? $info->is_repeal;
                }
                $info->save();
                StaffRestTimeModel::query()
                    ->whereBetween('rest_time', [$info['start_time'], $info['end_time']])
                    ->update([
                        'is_agree' => $info->is_agree,
                        'is_repeal' => $info->is_repeal
                    ]);
                DB::commit();
                return success();
            } catch (\Exception $e) {
                DB::rollBack();
                Log::debug('员工休息同意或拒绝或撤销异常：' . var_export($e->getMessage(), true));
                return fail('', '操作失败！');
            }
        } else {
            return fail('', '没有找到申请记录！');
        }
    }

    /**
     *获取两个时间段内的所有日期
     * Author: zlf
     * Created at 2024/8/8 16:08
     * @param $startDate
     * @param $endDate
     * @return array
     */
    private static function getDatesInRange($startDate, $endDate): array
    {
        $dates = [];
        $current = Carbon::createFromFormat('Y-m-d', $startDate);
        $end = Carbon::createFromFormat('Y-m-d', $endDate);

        while ($current->lte($end)) {
            $dates[] = $current->format('Y-m-d');
            $current->addDay();
        }

        return $dates;
    }
}
